package com.systar.activity.process.online;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.systar.activity.IActivable;
import com.systar.activity.events.IActivityEvent;
import com.systar.activity.monitor.ActivityManager;
import com.systar.activity.monitor.ActivitySource;
import com.systar.activity.process.ActivityStack;

public class HttpNotifier implements Runnable, IActivable
{
	private static final String authoriseAttribute = "Authorization";
	private static final String authoriseValue = "BASIC YWRtaW46YWRtaW4="; // BASIC authentication admin/admin

	private final ActivityManager manager;
	private final ActivityStack eventStack;
	private final String serverPath;
	private URL serverURL;
	private HttpURLConnection connection;
	private ScheduledExecutorService scheduler;

	public HttpNotifier(ActivityManager manager, String serverPath)
	{
		this.manager = manager;
		this.serverPath = serverPath;
		eventStack = manager.createEventDelegation();
	}

	@Override
	public boolean isActive()
	{
		return (connection != null);
	}
	
	@Override
	public void activate()
	{
		try
		{
			scheduler = Executors.newSingleThreadScheduledExecutor();
			// establish connection to server
			connect();
			// send source declarations
			for (ActivitySource source : manager.getSources())
			{
				String parameters = source.marshal();
				post(parameters);
			}
			// run pump thread
			scheduler.scheduleWithFixedDelay(this, 0, 5, TimeUnit.SECONDS);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			connection = null;
		}
	}

	@Override
	public void deactivate()
	{
		scheduler.shutdown();
		disconnect();
	}
	
	private void connect() throws IOException
	{
		serverURL = new URL(serverPath + "/activity?action=push");
	}

	private void disconnect()
	{
		if (connection != null)
			connection.disconnect();
		connection = null;
	}
	
	private void post(String urlParameters) throws IOException
	{
		if ((serverURL == null) || (urlParameters == null))
			return;
		
		connection = (HttpURLConnection) serverURL.openConnection();
		connection.setDoOutput(true);
		connection.setRequestMethod("POST");
		//connection.setRequestProperty("charset", "utf-8");
		connection.setUseCaches (false);
		
		// add authentication header
		connection.setRequestProperty(authoriseAttribute, authoriseValue);

		OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
		writer.write(urlParameters);
		writer.flush();

		BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		String line;
		while ((line = reader.readLine()) != null) {
		    System.out.println(line);
		}
		writer.close();
		reader.close();		
	}

	@Override
	public void run()
	{
		// post activity events
		for (IActivityEvent event : eventStack.get())
		{
			String parameters = event.marshal();
			try
			{
				post(parameters);
			}
			catch (IOException e)
			{
				e.printStackTrace();
				// connection = null;
			}
		}
	}

}
